package org.erikaredmark.monkeyshines.menu;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JDialog;
import javax.swing.JPanel;
import org.erikaredmark.monkeyshines.KeyBindings;
public class KeyboardControlDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final int RIGHT_KEY_DRAW_X = 67;
private static final int RIGHT_KEY_DRAW_Y = 16;
private static final int LEFT_KEY_DRAW_X = 67;
private static final int LEFT_KEY_DRAW_Y = 47;
private static final int JUMP_KEY_DRAW_X = 67;
private static final int JUMP_KEY_DRAW_Y = 78;
private static final int OKAY_DRAW_X = 133;
private static final int OKAY_DRAW_Y = 120;
private static final int DIALOG_SIZE_X = 328;
private static final int DIALOG_SIZE_Y = 180;
private final BufferedImage BACKGROUND;
private final BufferedImage CONTEXT_RIGHT;
private final BufferedImage CONTEXT_LEFT;
private final BufferedImage CONTEXT_JUMP;
// model state information
// There is no 'original' as there is no 'cancel' button
private KeyBindings bindings;
{
try {
BACKGROUND = ImageIO.read(SoundControlDialog.class.getResourceAsStream("/resources/graphics/mainmenu/keyboard/keyboardMain.png") );
CONTEXT_RIGHT = ImageIO.read(SoundControlDialog.class.getResourceAsStream("/resources/graphics/mainmenu/keyboard/keyboardRight.png") );
CONTEXT_LEFT = ImageIO.read(SoundControlDialog.class.getResourceAsStream("/resources/graphics/mainmenu/keyboard/keyboardLeft.png") );
CONTEXT_JUMP = ImageIO.read(SoundControlDialog.class.getResourceAsStream("/resources/graphics/mainmenu/keyboard/keyboardJump.png") );
} catch (IOException e) {
throw new RuntimeException("Bad .jar, could not find graphics resources for keyboard binding system: " + e.getMessage(), e);
}
}
private KeyboardControlDialog(final KeyBindings current) {
this.bindings = current;
// JPanel will handle custom drawing.
JPanel mainPanel = new JPanel() {
private static final long serialVersionUID = 1L;
// Direct painting is responsible for background and left/right sound images
@Override public void paintComponent(Graphics g) {
g.drawImage(BACKGROUND,
0, 0,
BACKGROUND.getWidth(), BACKGROUND.getHeight(),
0, 0,
BACKGROUND.getWidth(), BACKGROUND.getHeight(),
null);
}
};
mainPanel.setLocation(0, 0);
mainPanel.setSize(DIALOG_SIZE_X, DIALOG_SIZE_Y);
mainPanel.setPreferredSize(new Dimension(DIALOG_SIZE_X, DIALOG_SIZE_Y) );
mainPanel.setMinimumSize(new Dimension(DIALOG_SIZE_X, DIALOG_SIZE_Y) );
mainPanel.setLayout(null);
add(mainPanel);
// Key controls
final KeyBinder rightBinder =
new KeyBinder(
CONTEXT_RIGHT,
new PropertyChangeListener() {
@Override public void propertyChange(PropertyChangeEvent event) {
int right = (Integer)event.getNewValue();
bindings = new KeyBindings(bindings.left, right, bindings.jump);
}
},
current.right);
rightBinder.setLocation(RIGHT_KEY_DRAW_X, RIGHT_KEY_DRAW_Y);
KeyBinder leftBinder =
new KeyBinder(
CONTEXT_LEFT,
new PropertyChangeListener() {
@Override public void propertyChange(PropertyChangeEvent event) {
int left = (Integer)event.getNewValue();
bindings = new KeyBindings(left, bindings.right, bindings.jump);
}
},
current.left);
leftBinder.setLocation(LEFT_KEY_DRAW_X, LEFT_KEY_DRAW_Y);
KeyBinder jumpBinder =
new KeyBinder(
CONTEXT_JUMP,
new PropertyChangeListener() {
@Override public void propertyChange(PropertyChangeEvent event) {
int jump = (Integer)event.getNewValue();
bindings = new KeyBindings(bindings.left, bindings.right, jump);
}
},
current.jump);
jumpBinder.setLocation(JUMP_KEY_DRAW_X, JUMP_KEY_DRAW_Y);
mainPanel.add(rightBinder);
mainPanel.add(leftBinder);
mainPanel.add(jumpBinder);
// Okay button
OkayButton okayButton = new OkayButton(new ActionListener() {
@Override public void actionPerformed(ActionEvent arg0) {
setVisible(false);
}
});
okayButton.setLocation(OKAY_DRAW_X, OKAY_DRAW_Y);
mainPanel.add(okayButton);
}
/**
*
* Launches the key control dialog, using the current key bindings as the initial model, and returning a key bindings
* object representative of the changes the user made. It is possible, if the user makes no changes, for the object
* returned to be equal to the parameter.
*
* @param current
* the current key bindings
*
* @return
* the newly modified key bindings. May be equal to the original key bindings semantically
*
*/
public static KeyBindings launch(final KeyBindings current) {
KeyboardControlDialog dialog = new KeyboardControlDialog(current);
dialog.setModal(true);
dialog.setUndecorated(true);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
assert dialog.bindings != null;
return dialog.bindings;
}
}